package com.sl.pages;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import com.google.common.collect.Lists;
import com.sl.utils.JavaScripts;
import com.sl.utils.WaitForElement;
import com.sl.utils.WindowsStatus;

/**
 * Класс выполняющий общее поведение для всех страниц.
 * @author dgrigoriev
 *
 */
public abstract class Page {
	
	protected WebDriver driver;
	protected PageManager pageManager;
	protected JavaScripts js;
	protected WaitForElement wfe;
	
	public WindowsStatus ws;
	
	
	public Page(PageManager pageManager){
		
		this.pageManager = pageManager;
		driver = pageManager.getWebDriver();
		wfe = new WaitForElement(driver);
		js = new JavaScripts(driver);
		ws = WindowsStatus.getInstance();
		
	}
	
	public void type(WebElement webElement, String text){		
		webElement.clear();
		webElement.sendKeys(text);
	}
	
	
	public WebDriver getWebDriver(){
		return driver;
	}	
	
	/**
	 * Метод ожидает новый попап
	 * @return Page
	 */
	public Page incPopup(){
		ws.incPC();
		wfe.waitForAddPopup(ws.getPC());
		return this;
	}

	/**
	 * Метод ожидает пока закрытый попап не исчезнет из DOM
	 * @return Page
	 */
	public Page decPopup(){
		int countPopup = ws.getPC();
		By by = By.cssSelector("[additional-view='"+countPopup+"']");		
		if(isElementPresent(by))
			wfe.waitForClosePopup(countPopup);
			ws.decPC();
		return this;
	
	}
	
	/**
	 * Метод проверяет видимость элемента на странице, в случае фэйла переключает на нужный таб
	 * @param на вход принимает элемент (WebElement)
	 * @return WebElement
	 */
	public WebElement insideTab(WebElement element){
		
		try{
			if(!element.isDisplayed()){	
				String label;
				if(element.getTagName().equals("section"))
					label = js.getHiddenLabel(element.findElement(By.xpath(".//h3")));									
				else
					label = js.getHiddenLabel(element.findElement(By.xpath("./ancestor::section[@class='form-group nav-item']/h3/a")));
				
				if(ws.getPC()>-1){
					List<WebElement> tabs = driver.findElements(By.xpath("//*[@additional-view][last()]//ul[@class='nav nav-tabs']//a[normalize-space(text())=\""+label+"\"]"));					
					isDisplayedTabs(tabs);
				}
				else{
					List<WebElement> tabs = driver.findElements(By.xpath("//ul[@class='nav nav-tabs']//a[normalize-space(text())=\""+label+"\"]"));
					isDisplayedTabs(tabs);
				}
				
				
				
//				List<WebElement> tabs = driver.findElements(By.cssSelector("ul[class='nav nav-tabs']>li"));
//				 List<WebElement> allTabs = Lists.reverse(tabs);
//				for(WebElement tab : allTabs){
//					System.out.println("Element not visible. Get next TAB for search:");
//					if(tab.isDisplayed())
//					tab.click();
//					if(element.isDisplayed())
//						break;
//				}
			 }
			
		}catch(Exception e) {
			
		}	
		return element;
		
	}

	private void isDisplayedTabs(List<WebElement> allTabs) {
		for(WebElement tab : allTabs){
			System.out.println("Element not visible. Get next TAB for search:");
			if(tab.isDisplayed())
			tab.click();
		}
	}
	
	
	/**
	 * Метод проверяет есть ли на странице элемент
	 * @param на вход метод принимает локатор By
	 * @return boolean
	 */
	protected boolean isElementPresent(By by) {	
		driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
    try {	    	
    	driver.findElement(by);    	 
      return true;
    } catch(NoSuchElementException e) {
      return false;
    }finally{
    	 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    }
 }
	
	/**
	 * Метод выполняет очистку текстового поля и его заполнение
	 * @param WebElement
	 * @param String
	 */
	protected  void setTextfieldKeys(WebElement element, String value){
		if(value!=null){
			insideTab(element);
			type(element, value);
		}
	}
	
	/**
	 * Метод устанавливает необходимое значение в комбобоксе
	 * @param WebElement
	 * @param String
	 */
	protected void setComboboxKeys(WebElement element, String value){
		if(value!=null)
			pageManager.getCombobox(element).findValue(value);
	}
	
	/**
	 * Метод находит необходимое значение в list2list и выбирает его из списка
	 * @param WebElement
	 * @param String
	 */
	protected <T> void setList2listKeys(WebElement element, String value){
		if(value!=null){
			pageManager.getList2List(element).deleteAll().addValue(value);
		}
	}
	
	/**
	 * Метод устанавливает чекбокс в состояние в зависимости от передаваемого значения
	 * @param WebElement
	 * @param String
	 */
	protected void setCheckboxKeys(WebElement element, String value){
		if(value!=null)
			pageManager.getCheckbox(element).editCheckbox(value);		
		
	}
	
	
	/**
	 * Метод используется для работы с Finder.
	 * @param WebElement
	 * @param String
	 */
	protected <T> void setFinderKeys(WebElement element, String value){
		if(value!=null)
			pageManager.getFinder(element).setName(value).selectExistValue(value).clickOk();
		
	}
	
	
	

	
}
